//
//  PageTitleView.swift
//  HinsLive
//
//  Created by haoxian on 2019/4/17.
//  Copyright © 2019 Hins. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa


final class PageTitleView: UIView {

    private let titles: [String]
    private let style: PageTitleStyle
    
    private let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.showsHorizontalScrollIndicator = false
        v.scrollsToTop = false
        return v
    }()
    
    private lazy var splitLine: UIView = {
        let v = UIView()
        v.backgroundColor = style.common.splitLineColor
        return v
    }()
    
    private lazy var coverView: UIView = {
        let v = UIView()
        v.backgroundColor = style.coverView.color
        v.layer.cornerRadius = style.coverView.radius
        v.layer.masksToBounds = true
        return v
    }()
    
    private var titleItems = [PageTitleItem]()
    
    let itemDidTapSubject = PublishSubject<PageTitleItem>()

    var selectedIndex = 0 {
        willSet {
            if newValue == selectedIndex { return }
            itemSelectedDidChangeWith(oldIndex: selectedIndex, newIndex: newValue)
        }
    }
    
    var selectedItem: PageTitleItem {
        return titleItems[selectedIndex]
    }
    
    init(titles: [String], style: PageTitleStyle) {
        self.titles = titles
        self.style = style
        super.init(frame: .zero)
        backgroundColor = style.common.backgroundColor
        setupSubviews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        let splitLineHeight: CGFloat = 1
        scrollView.frame = CGRect(x: safeAreaInsets.left,
                                  y: safeAreaInsets.top,
                                  width: width - safeAreaInsetsWidth,
                                  height: height - safeAreaInsetsHeight - splitLineHeight)
        splitLine.frame = CGRect(x: 0, y: height - splitLineHeight, width: width, height: splitLineHeight)
        
        var previousItem: PageTitleItem?
        for item in titleItems {
            item.centerY = scrollView.boundsCenterY
            item.x = style.item.spacing + (previousItem?.maxX ?? 0)
            previousItem = item
        }
        scrollView.contentSize = CGSize(width: style.item.spacing + (previousItem?.maxX ?? 0), height: scrollView.height)
    }

}

private extension PageTitleView {
    func setupSubviews() {
        addSubview(scrollView)
        addSubview(splitLine)
        
        for i in 0..<titles.count {
            let title = titles[i]
            let item = PageTitleItem(title: title, style: self.style, index: i)
            _ = item.didTapSubject.subscribe(onNext: { [weak self] (item) in
                self?.selectedIndex = item.index
            })
            titleItems.append(item)
            scrollView.addSubview(item)
            if i == selectedIndex {
                item.isSelected = true
            }
        }
    }
    
    func itemSelectedDidChangeWith(oldIndex: Int, newIndex: Int) {
        titleItems[oldIndex].isSelected = false
        titleItems[newIndex].isSelected = true
        handleSelectedScroll(with: newIndex)
        itemDidTapSubject.onNext(titleItems[newIndex])
    }
    
    func handleSelectedScroll(with index: Int) {
        let item = titleItems[index]
        var offsetX = item.centerX - scrollView.centerX
        if offsetX < 0 {
            offsetX = 0
        }
        let maxOffsetX = scrollView.contentSize.width - scrollView.width
        if offsetX > maxOffsetX {
            offsetX = maxOffsetX
        }
        scrollView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: true)
    }
}

